<?php
/**
 * Project: AIGC
 * Author: moufer <moufer@163.com>
 * Date: 2024/8/31 17:18
 */

namespace module\user\logic;

use module\user\library\interface\FavoriteInterface;
use module\user\model\Favorite;
use module\user\model\User;
use mof\annotation\Inject;
use mof\exception\LogicException;
use mof\interface\UserInterface;
use mof\Logic;
use mof\Model;
use think\Collection;
use think\db\BaseQuery;
use think\db\exception\DbException;
use think\Paginator;

class FavoriteLogic extends Logic
{
    /** @var Favorite */
    #[Inject(Favorite::class)]
    protected $model;

    public function collect(int $userId, FavoriteInterface|Model $source): Model
    {
        //检测是否已经收藏
        $where = $this->getWhere($userId, $source);
        if ($this->model->where($where)->count()) {
            throw new LogicException('已收藏');
        }
        $model = $this->save($where);
        $source->updateFavoriteCount(1);
        return $model;
    }

    public function uncollect(int $userId, FavoriteInterface|Model $source)
    {
        $where = $this->getWhere($userId, $source);
        if (!$model = $this->model->where($where)->find()) {
            throw new LogicException('记录不存在');
        }
        $model->delete();
        $source->updateFavoriteCount(-1);
    }

    /**
     * 给数据加上收藏状态
     * @param int $userId
     * @param Collection $collection
     * @return void
     */
    public function appendStatus(int $userId, Collection $collection): void
    {
        if ($collection->count()) {
            $model = $collection[0];
            $ids = $collection->column('id');
            $sourceIds = Favorite::where(['user_id' => $userId])
                ->where('source_type', $model->sourceType())
                ->where('source_id', 'in', $ids)
                ->column('source_id');

            if (count($sourceIds)) {
                $collection->each(function ($item) use ($sourceIds) {
                    $item->setAttr('favorite', in_array($item->id, $sourceIds));
                });
            }
        }
    }

    /**
     * 用户收藏数据
     * @param int $userId
     * @param FavoriteInterface|Model $source
     * @param string $keyword
     * @param int $pageSize
     * @return Paginator
     * @throws DbException
     */
    public function userSourcesPaginate(int    $userId, FavoriteInterface|Model $source,
                                        string $keyword = '', int $pageSize = 10): Paginator
    {
        /** @var BaseQuery $query */
        $query = $source->alias('src')
            ->join($this->model->getName() . ' fa', 'fa.source_id=src.id')
            ->order('fa.id', 'desc')
            ->field('src.*')
            ->where([
                'user_id'     => $userId,
                'source_type' => $source->sourceType()
            ]);
        if ($keyword) {
            $query->whereLike('src.name', '%' . $keyword . '%');
        }
        $paginate = $query->paginate($pageSize, true);

        //增加收藏属性
        $paginate->getCollection()->each(function ($item) use ($source) {
            $item->setAttr('favorite', true);
            $item->visible($source->sourceFields())->append(['favorite']);
        });

        return $paginate;
    }

    protected function getWhere(int $userId, FavoriteInterface|Model $source): array
    {
        return [
            'user_id'     => $userId,
            'source_id'   => $source->sourceId(),
            'source_type' => $source->sourceType()
        ];
    }
}